package web

import (
	"net/http"
	"golang.org/x/net/websocket"
	"homeserver/logs"
	"homeserver/family"
)

//
// 与web终端通信消息格式
//
type Message struct {
	Type 	string			`json:"type"`
	Data 	interface{}		`json:"msg"`
}

//
// websocket 服务操作消息
//
type SevMsgData struct {
	DevId 		string		`json:"dev"`
	SevId		string		`json:"sev"`
	Operate 	string		`json:"operate"`
}

//
// 推送消息
//
type Post struct {
	Type 	string			`json:"type"`
	Data 	interface{}		`json:"post"`
}

//
// 下发的服务状态信息
//
type SevPostData struct {
	SevID	string		`json:"type"`
	DevId 	string		`json:"dev"`
	State   string		`json:"state"`
	Desc 	string		`json:"desc:"`
}

//
// 消息类型
//
const (
	// 下发消息类型
	WS_POST_TYPE_FAMILY = "family"
	WS_POST_TYPE_SEV	= "sev"
	WS_POST_TYPE_OPERATE = "operate"
	// 终端发回消息类型
	WS_MSG_TYPE_SEV = "sev"
	WS_MSG_TYPE_OPERATE = "operate"
)

//
// 用户连接接待
//
type Worker struct {
	memberId 	string

	conn 		*websocket.Conn

	message 	chan 	[]byte
	post 		chan 	[]byte
	notify 		chan 	[]byte

	end 		chan	bool
}

//
// 处理来自网页终端的消息
//
func (w *Worker) handleMessage(buffer []byte) error {
	webLogger.Info("websocket msg: %s", string(buffer))
	sendRequest(w.memberId, buffer)
	return nil
}

//
// 接收来自家庭中心的通知
//
func (w *Worker) Notify(buffer []byte) error {
	w.notify <- buffer
	return nil
}

//
// 向网页端推送消息
//
func (w *Worker) postMessage()  {
	for post := range w.post {
		webLogger.Info("websocket post: %s", string(post))
		if err := websocket.Message.Send(w.conn, string(post)); err != nil {
			webLogger.Error("websocket post err: ", err)
			continue
		}
	}
}

//
// 处理通知
//
func (w *Worker) handleNotify(notify []byte) error {
	w.post <- notify
	return nil
}

//
// 接收来自网页终端的消息
//
func (w *Worker) receiveMessage() {
	var rev string
	for {
		if err := websocket.Message.Receive(w.conn, &rev); err == nil {
			w.message <- []byte(rev)
		} else {
			close(w.message)
			return
		}
	}
}

//
// 连接服务
//
func MemberSevConn(ws *websocket.Conn) {
	defer ws.Close()

	//cookie, err := ws.Request().Cookie(COOKIE_NAME_MEMBER_ID)
	//if err != nil {
	//	return
	//}

	//webLogger.Info("websocket member_id: %s", cookie.Value)

	w := Worker{
		memberId: "18565381403",
		conn: ws,
	}

	webLogger.Info("websocket: %s - %s", ws.LocalAddr().String(), "connected")
	defer webLogger.Info("websocket: %s - %s", ws.LocalAddr().String(), "disconnected")

	// 接收消息
	w.message = make(chan []byte, 2)
	go w.receiveMessage()

	// 推送消息
	w.post = make(chan []byte, 2)
	go w.postMessage()
	defer close(w.post)

	// 接收通知
	w.notify = make(chan []byte, 2)
	defer close(w.notify)

	w.end = make(chan bool, 1)
	defer close(w.end)

	insertWorker(&w)
	defer removeWorker(&w)

	// 从家庭获取服务的最新状态
	go family.RequestSevAll(w.memberId, w.notify)

	// 业务循环
	for {
		select {

		case msg, ok := <- w.message:
			if ok {
				w.handleMessage(msg)
			} else {
				return
			}

		case notify, ok := <- w.notify:
			if ok {
				w.handleNotify(notify);
			}

		case <- w.end:
			return
		}
	}
}

// WebSocket 地址
var (
	webSocketAddr  = ""

	web_logger_file = "running/web_logger.txt"

	webLogger *logs.Logger
)

//
// 日志初始化
//
func init() {
	webLogger = logs.NewLogger(web_logger_file)
}

//
// WebSocket 服务
//
func SevWebSocket(addr string, end chan bool)  {

	http.Handle("/", websocket.Handler(MemberSevConn))
	if err := http.ListenAndServe(addr, nil); err != nil {
		webLogger.Error("WebSocket %s ListenAndServe: %s", addr, err)
	}
	end <- true
}

